{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Find the global minima of function $f(x) = x + 10sin(5x) + 7cos(4x)$"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Create individual (use binary encoding)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "from gaft.components import BinaryIndividual\n",
    "indv = BinaryIndividual(ranges=[(0, 10)], eps=0.001)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Create a population with `50` individuals"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "from gaft.components import Population\n",
    "population = Population(indv_template=indv, size=50).init()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Create genetic operators: selection, crossover, mutation"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 1. Tournament selection"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "from gaft.operators import TournamentSelection\n",
    "selection = TournamentSelection()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 2. Uniform crossover\n",
    "\n",
    "- `pc` is the probabililty of crossover operation\n",
    "- `pe` is the exchange probabiltiy for each possible gene bit in chromsome"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "from gaft.operators import UniformCrossover\n",
    "crossover = UniformCrossover(pc=0.8, pe=0.5)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 3. Flip bit mutation\n",
    "- `pm` is the probability of mutation"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "from gaft.operators import FlipBitMutation\n",
    "mutation = FlipBitMutation(pm=0.1)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Import an on-the-fly analysis plugin to output info to console"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "from gaft.analysis import ConsoleOutput"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Create an engine to run"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "from gaft import GAEngine\n",
    "\n",
    "engine = GAEngine(population=population, selection=selection,\n",
    "                  crossover=crossover, mutation=mutation,\n",
    "                  analysis=[ConsoleOutput])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Define target function to optimize\n",
    "\n",
    "here we try to find the global minima of $f(x) = x + 10sin(5x) + 7cos(4x)$\n",
    "\n",
    "***GAFT*** find the maxima of the fitness function, here we use the `engine.minimize` decorator to tell ***GAFT*** to find the minima."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [],
   "source": [
    "from math import sin, cos\n",
    "\n",
    "@engine.fitness_register\n",
    "@engine.minimize\n",
    "def fitness(indv):\n",
    "    x, = indv.solution\n",
    "    return x + 10*sin(5*x) + 7*cos(4*x)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Run the engine"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "gaft.ConsoleOutput   INFO     Generation number: 50 Population number: 50\n",
      "gaft.ConsoleOutput   INFO     Generation: 1, best fitness: 15.077, scaled fitness: 15.077\n",
      "gaft.ConsoleOutput   INFO     Generation: 2, best fitness: 15.164, scaled fitness: 15.164\n",
      "gaft.ConsoleOutput   INFO     Generation: 3, best fitness: 15.164, scaled fitness: 15.164\n",
      "gaft.ConsoleOutput   INFO     Generation: 4, best fitness: 15.164, scaled fitness: 15.164\n",
      "gaft.ConsoleOutput   INFO     Generation: 5, best fitness: 15.164, scaled fitness: 15.164\n",
      "gaft.ConsoleOutput   INFO     Generation: 6, best fitness: 15.164, scaled fitness: 15.164\n",
      "gaft.ConsoleOutput   INFO     Generation: 7, best fitness: 15.164, scaled fitness: 15.164\n",
      "gaft.ConsoleOutput   INFO     Generation: 8, best fitness: 15.164, scaled fitness: 15.164\n",
      "gaft.ConsoleOutput   INFO     Generation: 9, best fitness: 15.164, scaled fitness: 15.164\n",
      "gaft.ConsoleOutput   INFO     Generation: 10, best fitness: 15.164, scaled fitness: 15.164\n",
      "gaft.ConsoleOutput   INFO     Generation: 11, best fitness: 15.164, scaled fitness: 15.164\n",
      "gaft.ConsoleOutput   INFO     Generation: 12, best fitness: 15.164, scaled fitness: 15.164\n",
      "gaft.ConsoleOutput   INFO     Generation: 13, best fitness: 15.164, scaled fitness: 15.164\n",
      "gaft.ConsoleOutput   INFO     Generation: 14, best fitness: 15.164, scaled fitness: 15.164\n",
      "gaft.ConsoleOutput   INFO     Generation: 15, best fitness: 15.164, scaled fitness: 15.164\n",
      "gaft.ConsoleOutput   INFO     Generation: 16, best fitness: 15.164, scaled fitness: 15.164\n",
      "gaft.ConsoleOutput   INFO     Generation: 17, best fitness: 15.164, scaled fitness: 15.164\n",
      "gaft.ConsoleOutput   INFO     Generation: 18, best fitness: 15.164, scaled fitness: 15.164\n",
      "gaft.ConsoleOutput   INFO     Generation: 19, best fitness: 15.164, scaled fitness: 15.164\n",
      "gaft.ConsoleOutput   INFO     Generation: 20, best fitness: 15.164, scaled fitness: 15.164\n",
      "gaft.ConsoleOutput   INFO     Generation: 21, best fitness: 15.164, scaled fitness: 15.164\n",
      "gaft.ConsoleOutput   INFO     Generation: 22, best fitness: 15.164, scaled fitness: 15.164\n",
      "gaft.ConsoleOutput   INFO     Generation: 23, best fitness: 15.164, scaled fitness: 15.164\n",
      "gaft.ConsoleOutput   INFO     Generation: 24, best fitness: 15.164, scaled fitness: 15.164\n",
      "gaft.ConsoleOutput   INFO     Generation: 25, best fitness: 15.164, scaled fitness: 15.164\n",
      "gaft.ConsoleOutput   INFO     Generation: 26, best fitness: 15.164, scaled fitness: 15.164\n",
      "gaft.ConsoleOutput   INFO     Generation: 27, best fitness: 15.164, scaled fitness: 15.164\n",
      "gaft.ConsoleOutput   INFO     Generation: 28, best fitness: 15.164, scaled fitness: 15.164\n",
      "gaft.ConsoleOutput   INFO     Generation: 29, best fitness: 15.164, scaled fitness: 15.164\n",
      "gaft.ConsoleOutput   INFO     Generation: 30, best fitness: 15.164, scaled fitness: 15.164\n",
      "gaft.ConsoleOutput   INFO     Generation: 31, best fitness: 15.164, scaled fitness: 15.164\n",
      "gaft.ConsoleOutput   INFO     Generation: 32, best fitness: 15.164, scaled fitness: 15.164\n",
      "gaft.ConsoleOutput   INFO     Generation: 33, best fitness: 15.164, scaled fitness: 15.164\n",
      "gaft.ConsoleOutput   INFO     Generation: 34, best fitness: 15.164, scaled fitness: 15.164\n",
      "gaft.ConsoleOutput   INFO     Generation: 35, best fitness: 15.164, scaled fitness: 15.164\n",
      "gaft.ConsoleOutput   INFO     Generation: 36, best fitness: 15.164, scaled fitness: 15.164\n",
      "gaft.ConsoleOutput   INFO     Generation: 37, best fitness: 15.164, scaled fitness: 15.164\n",
      "gaft.ConsoleOutput   INFO     Generation: 38, best fitness: 15.164, scaled fitness: 15.164\n",
      "gaft.ConsoleOutput   INFO     Generation: 39, best fitness: 15.164, scaled fitness: 15.164\n",
      "gaft.ConsoleOutput   INFO     Generation: 40, best fitness: 15.164, scaled fitness: 15.164\n",
      "gaft.ConsoleOutput   INFO     Generation: 41, best fitness: 15.164, scaled fitness: 15.164\n",
      "gaft.ConsoleOutput   INFO     Generation: 42, best fitness: 15.164, scaled fitness: 15.164\n",
      "gaft.ConsoleOutput   INFO     Generation: 43, best fitness: 15.164, scaled fitness: 15.164\n",
      "gaft.ConsoleOutput   INFO     Generation: 44, best fitness: 15.164, scaled fitness: 15.164\n",
      "gaft.ConsoleOutput   INFO     Generation: 45, best fitness: 15.164, scaled fitness: 15.164\n",
      "gaft.ConsoleOutput   INFO     Generation: 46, best fitness: 15.164, scaled fitness: 15.164\n",
      "gaft.ConsoleOutput   INFO     Generation: 47, best fitness: 15.164, scaled fitness: 15.164\n",
      "gaft.ConsoleOutput   INFO     Generation: 48, best fitness: 15.164, scaled fitness: 15.164\n",
      "gaft.ConsoleOutput   INFO     Generation: 49, best fitness: 15.164, scaled fitness: 15.164\n",
      "gaft.ConsoleOutput   INFO     Generation: 50, best fitness: 15.164, scaled fitness: 15.164\n",
      "gaft.ConsoleOutput   INFO     Optimal solution: ([0.892333984375], 15.164338102247847)\n"
     ]
    }
   ],
   "source": [
    "engine.run(ng=50)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## After engine running, we can do something more..."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Get the best individual"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [],
   "source": [
    "best_indv = engine.population.best_indv(engine.fitness)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Get the solution"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[0.892333984375]"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "best_indv.solution"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### And the fitness value"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "15.164338102247847"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "engine.fitness(best_indv)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.5.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
